﻿@using Xunit;
@inherits TestContext
@code
{
    public FluentCheckboxThreeStatesTests()
    {
        JSInterop.Mode = JSRuntimeMode.Loose;
        Services.AddSingleton(LibraryConfiguration.ForUnitTests);
    }

    [Theory]
    [InlineData(false, true, true)] // Unchecked => Checked
    [InlineData(true, null, false)] // Checked => Indeterminate
    [InlineData(null, false, false)] // Indeterminate => Unchecked
    public void FluentCheckbox_ThreeStates(bool? initialState, bool? assertState, bool assertValue)
    {
        bool myValue = initialState ?? false;
        bool? myState = initialState;

        // Arrange && Act
        var cut = Render(@<FluentCheckbox Id="myCheck"
                ThreeState="true"
                @bind-CheckState="@myState"
                @bind-Value="@myValue" />);

        var component = cut.Find("fluent-checkbox");
        component.TriggerEvent("oncheckedchange", new CheckboxChangeEventArgs() { Checked = !myValue });


        // Assert
        Assert.Equal(assertState, myState);
        Assert.Equal(assertValue, myValue);
    }

    [Theory]
    [InlineData(false, null, false)] // Unchecked => Indeterminate
    [InlineData(null, true, true)] // Indeterminate => Checked
    [InlineData(true, false, false)] // Checked => Unchecked
    public void FluentCheckbox_ThreeStates_InverseOrder(bool? initialState, bool? assertState, bool assertValue)
    {
        bool myValue = initialState ?? false;
        bool? myState = initialState;

        // Arrange && Act
        var cut = Render(@<FluentCheckbox Id="myCheck"
                ThreeState="true"
                ThreeStateOrderUncheckToIntermediate="true"
                @bind-CheckState="@myState"
                @bind-Value="@myValue" />);

        var component = cut.Find("fluent-checkbox");
        component.TriggerEvent("oncheckedchange", new CheckboxChangeEventArgs() { Checked = !myValue });

        // Assert
        Assert.Equal(assertState, myState);
        Assert.Equal(assertValue, myValue);
    }

    [Fact]
    public void FluentCheckbox_ThreeStates_ShowIntermediateFalse()
    {
        // Start Intermediate
        bool? myState = null;

        // Arrange
        var cut = Render(@<FluentCheckbox Id="myCheck"
                ThreeState="true"
                ShowIndeterminate="false"
                @bind-CheckState="@myState" />);

        // Act
        var component = cut.Find("fluent-checkbox");

        // ... Intermediate => Uncheck
        // ... Uncheck => Check
        // ... Check => Uncheck (not Intermediate because )
        component.TriggerEvent("oncheckedchange", new CheckboxChangeEventArgs() { Checked = false });
        component.TriggerEvent("oncheckedchange", new CheckboxChangeEventArgs() { Checked = true });
        component.TriggerEvent("oncheckedchange", new CheckboxChangeEventArgs() { Checked = false });

        // Assert
        Assert.False(myState);
    }


    // Temporarily disable this test until we figure out how why the delay in checkbox breaks this
    // [Theory]
    // [InlineData(true, false)] // Unchecked => Checked
    // [InlineData(false, true)] // Checked => Unchecked
    // public async Task FluentCheckbox_ThreeStatesFalseAsync(bool initialValue, bool assertValue)
    // {
    //     bool myValue = initialValue;

    //     // Arrange && Act
    //     var cut = Render(@<FluentCheckbox Id="myCheck"
    //             ThreeState="false"
    //             @bind-Value="@myValue" />
    //     );


    //     var component = cut.Find("fluent-checkbox");
    //     component.TriggerEvent("oncheckedchange", new CheckboxChangeEventArgs() { Checked = !myValue });

    //     await Task.Delay(5);

    //     // Assert
    //     Assert.Equal(assertValue, myValue);
    // }

    [Fact]
    public void FluentCheckbox_Labels()
    {
        // Arrange
        var cut = Render(@<FluentCheckbox Label="MyLabel">My customized content</FluentCheckbox>);

        cut.Verify();
    }
}
